#include <STC15F2K60S2.H>
#include "key.h"
#include "init.h"
#include "led.h"
#include "seg.h"

// 变量申明
// 按键
idata unsigned char Key_Old, Key_Val, Key_Up, Key_Down;
// 数码管
idata unsigned char Seg_Buf[8] = {10, 10, 10, 10, 10, 10, 10, 10};
idata unsigned char Seg_Pos;
// LED
idata unsigned char ucLed[8] = {0, 0, 0, 0, 0, 0, 0, 0};
// 定时
idata unsigned char uwTick = 0;

// PWM
idata unsigned char pwm_period  = 12; // PWM周期
idata unsigned char pwm_compare = 12; // PWM占空比 3 6 9 12

// 函数申明
void Key_Proc()
{
    Key_Val  = Key_Read();
    Key_Down = Key_Val & (Key_Val ^ Key_Old);
    Key_Up   = ~Key_Val & (Key_Val ^ Key_Old);
    Key_Old  = Key_Val;
}

void Seg_Proc()
{
}

void Led_Proc()
{
}

/*AD读取*/
void Get_AD()
{
}

// 定时器
void Timer1Init(void) // 1毫秒@12.000MHz
{
    AUXR |= 0x40; // 定时器时钟1T模式
    TMOD &= 0x0F; // 设置定时器模式
    TL1 = 0x20;   // 设置定时初值
    TH1 = 0xD1;   // 设置定时初值
    TF1 = 0;      // 清除TF1标志
    TR1 = 1;      // 定时器1开始计时
    ET1 = 1;      // 允许定时器1中断
    EA  = 1;      // 允许CPU中断
}

void Timer1_ISR(void) interrupt 3
{
    uwTick++;
    Seg_Pos = (++Seg_Pos) % 8;
    if (Seg_Buf[Seg_Pos] > 20)
        Seg_Disp(Seg_Pos, Seg_Buf[Seg_Pos] - ',', 1); // 显示小数点的情况
    else
        Seg_Disp(Seg_Pos, Seg_Buf[Seg_Pos], 0); // 不显示小数点的情况
                                                // pwm调光周期
    if (++pwm_period >= 12)
        pwm_period = 0;
    if (pwm_period >= pwm_compare)
        Led_Disp(ucLed);
    else
        Led_off();
}

// 调度器
typedef struct
{
    void (*task_func)(void); // 任务函数
    unsigned int rate_ms;    // 执行周期
    unsigned int last_ms;    // 上次执行时间
} task_t;

idata task_t schedular_task[] = {
    {Led_Proc, 1, 0},
    {Key_Proc, 10, 0},
    {Get_AD, 160, 0},
    {Seg_Proc, 300, 0}};

idata unsigned char task_num; // 任务数量
void Schedular_Init()
{
    task_num = sizeof(schedular_task) / sizeof(task_t);
}

void Schedular_Run()
{
    unsigned int now_time = uwTick;
    unsigned char i       = 0;
    for (i = 0; i < task_num; i++) {
        if (now_time >= schedular_task[i].last_ms + schedular_task[i].rate_ms) {
            schedular_task[i].task_func();
            now_time = schedular_task[i].last_ms;
        }
    }
}

void main()
{
    while (1) {
    }
}
